package com.hh.listener;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.util.ListUtils;
import com.hh.entity.domain.User;
import com.hh.service.UserService;
import lombok.extern.slf4j.Slf4j;

import java.util.List;

import static com.alibaba.excel.read.listener.PageReadListener.BATCH_COUNT;

/**
 * com.hh.listener
 *
 * @author hanhui
 * @version 1.0
 * @since 2025/8/21 20:01
 **/
@Slf4j
public class UserExcelListener extends AnalysisEventListener<User> {

    private final UserService userService;

    public UserExcelListener(UserService userService) {
        this.userService = userService;
    }

    private static final int BATCH_SIZE = 100;

    private final List<User> cachedDataList = ListUtils.newArrayListWithExpectedSize(BATCH_SIZE);

    /**
     * 异常处理方法
     *
     * @param exception 解析过程中发生的异常对象
     * @param context   分析上下文信息
     * @throws Exception 抛出异常，供上层调用者处理
     */
    @Override
    public void onException(Exception exception, AnalysisContext context) throws Exception {
        // 记录错误日志，包含异常堆栈信息
        log.error("======>>>解析异常：", exception);
        // 将异常继续向上抛出，由调用者处理
        throw exception;
    }

    /**
     * 重写父类的invoke方法，用于处理每一条解析出来的用户数据
     *
     * @param user            解析出来的用户对象
     * @param analysisContext 分析上下文对象，提供额外的分析信息
     */
    @Override
    public void invoke(User user, AnalysisContext analysisContext) {
        // 打印解析到的数据日志
        log.info("解析到一条数据:{}", user);
        // 将解析到的用户数据添加到缓存列表中
        cachedDataList.add(user);
        // 当缓存数据量达到预设的批次处理数量时
        if (cachedDataList.size() >= BATCH_COUNT) {
            // 处理缓存的数据，比如说入库。。。
            userService.saveBatch(cachedDataList);
            // 然后清空
            cachedDataList.clear();
        }
    }

    /**
     * 所有数据解析完成后的回调方法
     *
     * @param analysisContext 分析上下文信息，可以获取到当前sheet等基本信息
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {  // 所有数据解析完成后的回调方法
        log.info("sheet={} 所有数据解析完成！", analysisContext.readSheetHolder().getSheetName());  // 记录日志，输出当前sheet名称和解析完成的信息
    }
}